package com.daxia.bumall.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.daxia.bumall.common.Logs;
import com.daxia.bumall.common.PinguanType;
import com.daxia.bumall.common.UserType;
import com.daxia.bumall.dao.BrandDAO;
import com.daxia.bumall.dto.BrandDTO;
import com.daxia.bumall.dto.FactoryInfoDTO;
import com.daxia.bumall.dto.UserDTO;
import com.daxia.bumall.model.Brand;
import com.daxia.bumall.support.Page;
import com.daxia.bumall.util.BeanMapper;

@Service
public class BrandService {
	
	@Autowired
	private BrandDAO brandDAO;
	@Autowired
	private FactoryInfoService factoryInfoService;
	@Autowired
	private UserService userService;
	
	public List<BrandDTO> find(BrandDTO query, Page page) {
		List<Brand> models = brandDAO.find(query, page);
		List<BrandDTO> dtos = toDTOs(models);
		return dtos;
	}
	
	public List<BrandDTO> findAll() {
		return this.find(new BrandDTO(), null);
	}
	
	public List<BrandDTO> find(int count) {
		Page page = new Page();
		page.setPage(1);
		page.setPageSize(count);
		return this.find(new BrandDTO(), page);
	}
	
	public Long create(BrandDTO dto) {
		Brand model = new Brand();
		toModel(model, dto);
		return brandDAO.create(model);
	}
	
	public BrandDTO load(Long id) {
	    Brand model = brandDAO.load(id);
	    return toDTO(model);
    }

	public void updateAllFields(BrandDTO dto) {
		Brand model = brandDAO.load(dto.getId());
		toModel(model, dto);
		brandDAO.update(model);
    }

	public void deleteByIds(Long[] ids) {
		if (ids != null) {
			for (Long id : ids) {
				brandDAO.deleteById(id);
			}
		}
    }
	
	public void deleteById(Long id) {
		this.deleteByIds(new Long[] {id});
	}

	public BrandDTO findOne(BrandDTO query) {
		Brand model = brandDAO.findOne(query);
		return toDTO(model);
	}
	
	public List<BrandDTO> toDTOs(List<Brand> models) {
		if (CollectionUtils.isEmpty(models)) {
			return new ArrayList<BrandDTO>(0);
		}
		List<BrandDTO> dtos = new ArrayList<BrandDTO>(models.size());
		for (Brand model : models) {
	        BrandDTO dto = toDTO(model);
	        dtos.add(dto);
        }
	    return dtos;
    }
    
    private BrandDTO toDTO(Brand model) {
		if (model == null) {
			return null;
		}
		BrandDTO dto = BeanMapper.map(model, BrandDTO.class);
		
		return dto;
	}
	
	private void toModel(Brand model, BrandDTO dto) {
		BeanMapper.copy(dto, model);
    }
	
	@SuppressWarnings("unused")
	private List<Brand> toModels(List<BrandDTO> dtos) {
		if (CollectionUtils.isEmpty(dtos)) {
			return new ArrayList<Brand>(0);
		}
		List<Brand> models = new ArrayList<Brand>(dtos.size());
		for (BrandDTO dto : dtos) {
	        Brand model = new Brand();
	        toModel(model, dto);
	        models.add(model);
        }
		return models;
	}

	public List<BrandDTO> findByTag(PinguanType type) {
		BrandDTO q = new BrandDTO();
		q.setPinguanType(type.getValue());
		Page page = new Page();
		page.setPage(1);
		page.setPageSize(4);
		return this.find(q, page);
	}
	
	public BrandDTO findByName(String name) {
		BrandDTO query = new BrandDTO();
		query.setName(name);
		return this.findOne(query);
	}

	@Transactional
	public void doUpload(MultipartFile mf) throws Exception {

		Workbook book = WorkbookFactory.create(mf.getInputStream());

		Sheet sheet = book.getSheetAt(0);
		// 获取左上角的单元格
		int count = 0;
		Iterator<Row> iterable = sheet.rowIterator();
		iterable.next();
		FactoryInfoDTO lastFactoryInfo = null;
		while (iterable.hasNext()) {
			Row row = iterable.next();
			if (row.getCell(0) == null && lastFactoryInfo == null) {
				Logs.COMMON.debug("cell 0 and lastFactoryInfo is null");
				continue;
			}
			String factoryName;
			if (row.getCell(0) == null) {
				factoryName = lastFactoryInfo.getUser().getUsername();
			} else {
				factoryName = row.getCell(0).getStringCellValue().trim();
			}
			if (StringUtils.isBlank(factoryName) && lastFactoryInfo == null) {
				throw new RuntimeException("工厂名不能为空");
			}
			if (StringUtils.isBlank(factoryName)) {
				factoryName = lastFactoryInfo.getUser().getUsername();
			}
			FactoryInfoDTO factoryInfo = factoryInfoService.findByExactName(factoryName);
			if (factoryInfo == null) {
				UserDTO user = new UserDTO();
				user.setUsername(factoryName);
				user.setType(UserType.Factory.getValue());
				user.setCreatetime(new Date());
				Long userId = userService.create(user);
				user = userService.load(userId);
				factoryInfo = new FactoryInfoDTO();
				factoryInfo.setUser(user);
				Long factoryInfoId = factoryInfoService.create(factoryInfo);
				factoryInfo = factoryInfoService.load(factoryInfoId);
				lastFactoryInfo = factoryInfo;
			}
			String brandName = row.getCell(1).getStringCellValue().trim();
			String brandImageFileName = row.getCell(2).getStringCellValue().trim();
			
			BrandDTO dbBrand = this.findByName(brandName);
			if (dbBrand == null) {
				Logs.COMMON.debug("create brand " + brandName);
				dbBrand = new BrandDTO();
				dbBrand.setName(brandName);
				dbBrand.setImportImageName(brandImageFileName);
				dbBrand.setFactoryInfo(factoryInfo);
				Long brandId = this.create(dbBrand);
				dbBrand.setId(brandId);
			} else {
				Logs.COMMON.debug("brand " + brandName + " exists");
			}
			
		}
			
	}

	public List<BrandDTO> findRecommended() {
		BrandDTO query = new BrandDTO();
		query.setRecommend(1);
		return this.find(query, null);
	}
}
